package com.atguigu.tingshu.common.login;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @date: 2024/7/27 15:14
 * @author: yz
 * @version: 1.0
 */
@Aspect
@Component
@Slf4j
public class GuiGuAspect {


    @Autowired
    private RedisTemplate redisTemplate;
    /**
     *
     * 用户拦截切面定义处理
     *
     * @param joinPoint
     * @param guiGuLogin
     * @return
     */
    //自定义切面类 @GuiguLogin
    //围绕被注解作用的方法
    //该方法需要拿到请求头中的token spring中有类 RequestContextHolder可以在请求达到任何位置都能拿到请求头信息和响应信息
    //拿到请求头信息后 从redis中获取用户信息 拿到i后进行校验判断是否拿到数据和该方法是否需要进行登录校验
    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..))&&@annotation(guiGuLogin)")
    @SneakyThrows
    public Object doConcurrentOperation(ProceedingJoinPoint joinPoint,GuiGuLogin guiGuLogin){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = sra.getRequest();
        String token = request.getHeader("token");
        String loginKey=RedisConstant.USER_LOGIN_KEY_PREFIX + token;
        UserInfoVo userInfoVo = (UserInfoVo) redisTemplate.opsForValue().get(loginKey);
        if (guiGuLogin.required()&& userInfoVo==null){
            // 拦截--响应208
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        if (userInfoVo!=null){
            AuthContextHolder.setUserId(userInfoVo.getId());
        }
        Object proceed = joinPoint.proceed();
        AuthContextHolder.removeUserId();

        return proceed;
    }


//    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(guiGuLogin)")
//    public Object doConcurrentOperation(ProceedingJoinPoint joinPoint,GuiGuLogin guiGuLogin){
//        try {
//            Object object = null;
//            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//            ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;
//            HttpServletRequest request = sra.getRequest();
//            String token = request.getHeader("token");
//            String loginKey=RedisConstant.USER_LOGIN_KEY_PREFIX + token;
//            UserInfoVo userInfoVo = (UserInfoVo) redisTemplate.opsForValue().get(loginKey);
//            if (guiGuLogin.required()&& userInfoVo==null){
//               // 拦截--响应208
//                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
//            }
//            //登录--存储userid--threadlocal
//            if(userInfoVo!=null){
//
//                AuthContextHolder.setUserId(userInfoVo.getId());
//            }
//            object = joinPoint.proceed();
//            //清除threadlocal--防止内存泄漏 --防止信息泄露
//            AuthContextHolder.removeUserId();
//            return object;
//        } catch (Throwable e) {
//            throw new RuntimeException(e);
//        }
//    }

//    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(guiGuLogin)")
//    @SneakyThrows
//    public Object doConcurrentOperation(ProceedingJoinPoint joinPoint,GuiGuLogin guiGuLogin)  {
//        Object proceed =null;
//
//        //获取用户请求对象
//        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//        ServletRequestAttributes attributes= (ServletRequestAttributes) requestAttributes;
//        HttpServletRequest request = attributes.getRequest();
//        //获取请求头中存储的token
//        String token = request.getHeader("token");
//        //指定存储key
//        String loginKey=RedisConstant.USER_LOGIN_KEY_PREFIX + token;
//        //尝试充redis中获取user信息
//        UserInfoVo userInfoVo= (UserInfoVo) redisTemplate.opsForValue().get(loginKey);
//
//        //判断是否需求拦截
//        if(guiGuLogin.required()&& userInfoVo==null){
//
//            //拦截--响应208
//            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
//
//        }
//
//
//
//
//        //登录--存储userid--threadlocal
//        if(userInfoVo!=null){
//
//            AuthContextHolder.setUserId(userInfoVo.getId());
//        }
//
//        //执行目标方法
//       proceed = joinPoint.proceed();
//
//
//        //清除threadlocal--防止内存泄漏 --防止信息泄露
//        AuthContextHolder.removeUserId();
//
//
//
//
//        return proceed;
//    }




}
